/*
 * @Author: 晴鸢. 3013433857@qq.com
 * @Date: 2025-09-27 14:12:00
 * @LastEditors: 晴鸢. 3013433857@qq.com
 * @LastEditTime: 2025-09-27 15:55:00
 * @FilePath: /Learn/Threadpool/ThreadPool.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#pragma

#include<iostream>
#include<pthread.h>
#include<vector>
#include<string>
#include<queue>
#include<unistd.h>
using namespace std;
struct ThreadInfo
{
    pthread_t tid;
    string name;
};

//默认为线程池中有多少线程
static const int defaultnum=5;
template<class T>
class ThreadPool
{
public:
    void Lock()
    {
        pthread_mutex_lock(&_mutex);
    }
    void unLock()
    {
        pthread_mutex_unlock(&_mutex);
    }
    void wakeup()
    {
        //唤醒
        pthread_cond_signal(&_cond);
    }
    void Threadsleep()
    {
        //阻塞等待
        pthread_cond_wait(&_cond,&_mutex);
    }
    bool isQueueEmpty()
    {
        return tasks.empty();
    }
    string Getname(pthread_t tid)
    {
        for(auto ti:threads)
        {
            if(ti.tid==tid) return ti.name;
        }
        return "none";
    }
public:
    ThreadPool()
    {}
    ThreadPool(int num=defaultnum)
        :threads(num)
    {
        pthread_mutex_init(&_mutex,nullptr);
        pthread_cond_init(&_cond,nullptr);
    }
    //实际上为void* HandlerTask(ThreadPool* this, void* args);与线程函数的参数不匹配
    //因此，要么设置为全局对象，要么设置为静态成员
    //静态函数无法直接调用普通成员函数，可将this传入args中解决问题
    static void* HandlerTask(void*args)
    {
        ThreadPool<T>* td=static_cast<ThreadPool<T>*>(args);
        string name=td->Getname(pthread_self());
        while(1)
        {
            td->Lock();
            //避免错误唤醒的问题
            while(td->isQueueEmpty())
            {
               td->Threadsleep();
            }
            T t=td->Pop();
            td->unLock();
            t();//Task.hpp中的仿函数，在锁外可以并发执行任务
            cout<<name<<" run,result:"<<t.Getresult()<<endl;
        }
    }
    void start()
    {
        int num=threads.size();    
        for(int i=0;i<num;i++)
        {
            threads[i].name="thread "+to_string(i+1);
            pthread_create(&(threads[i].tid),nullptr,HandlerTask,this);
        }
    }
    T Pop()
    {
        T t=tasks.front();
        tasks.pop();
        return t;
    }
    void Push(const T&t)
    {
        Lock();
        tasks.push(t);
        wakeup();
        unLock();
    }

    ~ThreadPool()
    {
        pthread_mutex_destroy(&_mutex);
        pthread_cond_destroy(&_cond);
    }
private:
    vector<ThreadInfo> threads;//用于维护线程
    queue<T> tasks;//需要处理任务的等待队列
    pthread_mutex_t _mutex;
    pthread_cond_t _cond;
};
